package com.jushu.storbox.manager;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import com.jushu.storbox.filter.DirFilter;
import com.jushu.storbox.filter.FileFilter;

public class DirectoryManager {
	private static DirectoryManager instance = new DirectoryManager();

	private DirectoryManager() {
	}

	public static DirectoryManager getInstance() {
		return instance;
	}

	/**
	 * Returns all directories and files from a directory sorted by natural
	 * order and directories first.
	 * 
	 * @param directory
	 *            The directory to display content from
	 * @return {@link ArrayList}<Files>
	 */
	public ArrayList<File> getDirectoryListing(File directory) {
		return this.getDirectoryListing(directory, null);
	}

	public ArrayList<File> getDirectoryListing(File directory, String[] mFilters) {
		ArrayList<File> files = new ArrayList<File>();
		ArrayList<File> dirs = new ArrayList<File>();
		if (null == mFilters)// type for all files(include directory)
		{
			File[] listFiles = directory.listFiles();
			convertArraysToList(listFiles, files);
			File[] listFiles2 = directory.listFiles(new DirFilter());
			convertArraysToList(listFiles2, dirs);
			removeDirs(files, dirs);
			return addResult(directory, files, dirs);
		} else {
			File[] listFiles = directory.listFiles(new DirFilter());
			convertArraysToList(listFiles, dirs);

			if (mFilters != null) {
				File[] listFiles2 = directory
						.listFiles(new FileFilter(mFilters));
				convertArraysToList(listFiles2, files);
			}
			return addResult(directory, files, dirs);
		}
	}
	
	
	public ArrayList<File> getFolderList(File directory) {
		File[] listFiles = directory.listFiles(new DirFilter());
		ArrayList<File> dirs = new ArrayList<File>();
		convertArraysToList(listFiles, dirs);
		return dirs;
	}

	/**
	 * @param root
	 * @param suffix
	 */
	public void getFileListing(File root, String[] suffix, List<File> result) {
		File[] files = root.listFiles();
		if (null != files) {
			for (File file : files) {
				if (file.isDirectory()) {
					getFileListing(file, suffix, result);
				} else {
					String fileName = file.getName();
					if (null != suffix) {
						for (int i = 0; i < suffix.length; i++) {
							if (fileName.endsWith(suffix[i])) {
								result.add(file);
							}
						}
					}
				}
			}
		}
	}

	/**
	 * 
	 * @param listFiles
	 *            Can't empty
	 * @param files
	 *            can empty
	 */
	private void convertArraysToList(File[] listFiles, ArrayList<File> files) {
		if (null == files) {
			if (null != listFiles) {
				files = new ArrayList<File>(Arrays.asList(listFiles));
			}
		} else {
			if (null != listFiles) {
				files.addAll(Arrays.asList(listFiles));
			}
		}
	}

	/**
	 * Remove directories from files
	 * 
	 * @param files
	 *            The files which directories have contained by files
	 * @param dirs
	 *            The directories to be remove
	 */
	private void removeDirs(List<File> files, List<File> dirs) {
		if (null != files && null != dirs) {
			for (int i = 0; i < files.size(); i++) {
				if (files.get(i).isDirectory()) {
					files.remove(i);
					--i;
				}
			}
		}
	}

	/**
	 * To get data which contains files and directories
	 * 
	 * @param directory
	 * @param files
	 * @param dirs
	 * @return
	 */
	private ArrayList<File> addResult(File directory, List<File> files,
			List<File> dirs) {
		ArrayList<File> result = new ArrayList<File>();

		if (dirs != null) {
			Collections.sort(dirs);
		}

		if (files != null) {
			Collections.sort(files);
		}

		if (null != dirs && dirs.size() > 0)// add directory to result
		{
			result.addAll(dirs);
		}

		if (null != files && files.size() > 0)// add file to result
		{
			result.addAll(files);
		}
		return result;
	}

	public interface OnFileListCallback {

		/**
		 * @param list
		 */
		public void searchFileListInfo(List<File> list);

	}
}
